// metrics data structure
//基本功能 inc/dec/snapshot
use dashmap::DashMap;
use std::fmt::{Display, Formatter};
use std::ops::Deref;
use std::sync::Arc;

#[derive(Debug, Clone)]
pub struct MetricsDash {
    pub data: Arc<DashMap<String, i64>>,
}

impl Default for MetricsDash {
    fn default() -> Self {
        Self::new()
    }
}

impl MetricsDash {
    pub fn new() -> MetricsDash {
        MetricsDash {
            data: Arc::new(DashMap::new()),
        }
    }
    #[allow(dead_code)]
    pub fn inc(&self, key: impl Into<String>) {
        self.data
            .entry(key.into())
            .and_modify(|v| *v += 1)
            .or_insert(1);
    }

    #[allow(dead_code)]
    pub fn des(&self, key: impl Into<String>) {
        self.data
            .entry(key.into())
            .and_modify(|v| *v -= 1)
            .or_insert(1);
    }

    #[allow(dead_code)]
    pub fn snapshot(&self) -> DashMap<String, i64> {
        self.data.deref().clone()
    }
}

impl Display for MetricsDash {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        for x in self.data.iter() {
            writeln!(f, "{}: {}", x.key(), x.value())?;
        }
        Ok(())
    }
}
